﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ServiceModel;

using System.Data.Linq.Mapping;
using System.Data.Linq;

using System.Runtime.Serialization;

using System.Messaging;

using System.Windows.Forms;
using System.Transactions;


namespace Ex3 {

    [DataContract(Namespace = "MeuNamespace")]
    [Table(Name = "Contas")]
    public class Conta {
        [DataMember(IsRequired = true)]
        [Column(IsPrimaryKey = true, UpdateCheck = UpdateCheck.Never)]
        public int Numero { get; set; }
        [Column(Name = "Titular", UpdateCheck = UpdateCheck.Never)]
        [DataMember(IsRequired = true)]
        public string Titular { get; set; }
        [Column(UpdateCheck = UpdateCheck.Never)]
        [DataMember(IsRequired = true)]
        public float Saldo { get; set; }
    }

    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IServicoMSMQ {

        [OperationContract(IsOneWay = true, IsInitiating = true, IsTerminating = false)]
        void inserirConta(String g, Conta c, int s);

        [OperationContract(IsOneWay = true, IsInitiating = true, IsTerminating = false)]
        void alterarConta(String g, Conta c, int s);

        [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = true)]
        void terminaEnvio();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class Servico : IServicoMSMQ {

        string connString = @"Data Source=localhost;Initial Catalog=lab5;Integrated Security=true";

        [OperationBehavior(TransactionAutoComplete = false, TransactionScopeRequired = true)]
        public void inserirConta(String g, Conta c, int s) {
            DataContext dc = new DataContext(connString);
            Table<Conta> tc = dc.GetTable<Conta>();
            tc.InsertOnSubmit(c);
            dc.SubmitChanges();
            Console.WriteLine("Titular: {0}\t{1}", c.Titular, s);

        }

        [OperationBehavior(TransactionAutoComplete = false, TransactionScopeRequired = true)]
        public void alterarConta(String g, Conta c, int s) {
            Console.WriteLine("AlterarConta");
            DataContext dc = new DataContext(connString);
            Table<Conta> tc = dc.GetTable<Conta>();
            tc.Attach(c, true);
            try {
                dc.SubmitChanges(ConflictMode.ContinueOnConflict);
                Console.WriteLine("Conta alterada");
            } catch (ChangeConflictException e) {
                Console.WriteLine("Erro ao alterar a conta");
                throw;
            }
            Console.WriteLine("Titular: {0}\t{1}", c.Titular, s);
        }

        [OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)]
        public void terminaEnvio() {
            Console.WriteLine("Mensagem agregada processada!");
        }
    }

    class Program {
        static void Main(string[] args) {
            if (!MessageQueue.Exists(@".\private$\filaWCF"))
                MessageQueue.Create(@".\private$\filaWCF", true);  //ATENÇÃO: por omissão, a fila tem de ser transacciona

            NetMsmqBinding b = new NetMsmqBinding();
            b.ReceiveErrorHandling = ReceiveErrorHandling.Drop;

            ServiceHost host =
                    new ServiceHost(typeof(Servico));

            host.Open();
            Console.WriteLine("Serviço iniciado. Enter para terminar");
            Console.ReadLine();
            host.Close();
        }
    }
}